import sys

import PySide6
import serial
import serial.tools.list_ports
from PySide6.QtCore import QSize, QRegularExpression
from PySide6.QtGui import QImage, QPixmap, QIcon, QRegularExpressionValidator
from PySide6.QtWidgets import QWidget, QApplication, QGridLayout, QGroupBox, QLabel, QPushButton, QLineEdit, QCheckBox, \
    QComboBox, QMessageBox
import resources.resources_rc


class Tcp_Reset_Manage(QWidget):
    def __init__(self, parent=None, config=None):
        super(Tcp_Reset_Manage, self).__init__()
        # 获取变量
        self.config = config
        if self.config == None:
            self.config = {
                "pass_word": "12341234",
                "check_echo": True,
                "check_save": True
            }
        self.signal_operat = parent.signal_operat


        self.initLayout()
        self.add_info_data()
        self.show()

    def initLayout(self):
        """ 创建视图 """
        # 初始化窗口
        self.setWindowTitle('重置TCP连接')
        self.setFixedSize(330, 250)
        self.setWindowIcon(QIcon(':/logo.ico'))
        self.layout = QGridLayout(self)

        self.group_serial = QGroupBox('串口设置')
        self.label_port = QLabel('串口号')
        self.button_get_com = QPushButton('获取可用串口')
        self.button_conn = QPushButton('打开串口')
        self.button_conn.setCheckable(True)
        self.button_conn.clicked.connect(self.com_conn)

        self.label_state = QLabel('串口状态:')
        self.button_state = QPushButton()
        self.button_state.setFixedSize(20, 20)
        self.button_state.setIconSize(QSize(18, 18))
        self.button_state.setStyleSheet('background-color: rgb(192, 192, 192);border-radius: 10px; border: 2px groove gray;border-style: outset;')
        self.pix_red = QPixmap.fromImage(QImage(':/red_button.png'))
        self.pix_green = QPixmap.fromImage(QImage(':/green_button.png'))
        self.icon_red = QIcon()
        self.icon_red.addPixmap(self.pix_red)
        self.icon_green = QIcon()
        self.icon_green.addPixmap(self.pix_green)
        self.button_state.setIcon(self.icon_red)
        self.label_password = QLabel('十六进制密码区:')
        self.lineedit_password = QLineEdit()
        reg = QRegularExpression('[a-fA-F0-9]+$')
        hex_validator = QRegularExpressionValidator(self)
        hex_validator.setRegularExpression(reg)
        self.lineedit_password.setValidator(hex_validator)
        self.lineedit_password.setMaxLength(8)
        self.lineedit_password.setPlaceholderText('请输入8位16进制字符')
        self.check_password = QCheckBox('显示/隐藏密码')
        self.check_password.setChecked(True)
        self.check_password.stateChanged.connect(self.check_change_password)
        self.check_save = QCheckBox('保存/不保存密码')
        self.check_save.setChecked(True)
        # self.check_save.stateChanged.connect(self.check_change_save)
        self.button_reset = QPushButton('重置下位机TCP通信')
        self.button_reset.setEnabled(False)
        self.button_reset.clicked.connect(self.reset_tcp)
        self.button_get_com.clicked.connect(self.get_com)
        self.combox_port = QComboBox()

        self.group_serial_layout = QGridLayout()

        self.layout.addWidget(self.group_serial, 0, 0, 1, 1)
        self.group_serial.setLayout(self.group_serial_layout)
        self.group_serial_layout.addWidget(self.label_port, 0, 0, 1, 1)
        self.group_serial_layout.addWidget(self.combox_port, 0, 1, 1, 1)
        self.group_serial_layout.addWidget(self.button_get_com, 0, 2, 1, 2)
        self.group_serial_layout.addWidget(self.button_conn, 1, 2, 1, 2)
        self.group_serial_layout.addWidget(self.label_state, 1, 0, 1, 1)
        self.group_serial_layout.addWidget(self.button_state, 1, 1, 1, 1)
        self.group_serial_layout.addWidget(self.label_password, 2, 0, 1, 2)
        self.group_serial_layout.addWidget(self.lineedit_password, 2, 2, 1, 2)
        self.group_serial_layout.addWidget(self.check_password, 3, 0, 1, 2)
        self.group_serial_layout.addWidget(self.check_save, 3, 2, 1, 2)
        self.group_serial_layout.addWidget(self.button_reset, 4, 0, 1, 4)

    def add_info_data(self):
        self.lineedit_password.setText(self.config['pass_word'])
        self.check_password.setChecked(self.config['check_echo'])
        self.check_password.setChecked(self.config['check_save'])

    def get_com(self):
        # 打印可用串口列表
        self.combox_port.clear()
        self.plist = list(serial.tools.list_ports.comports())
        if len(self.plist) <= 0:
            qm = QMessageBox.warning(self, '提示窗口', '未找到串口!请检查接线和电脑接口。', QMessageBox.Ok | QMessageBox.Cancel,
                                     QMessageBox.Ok)
        else:
            for i in list(self.plist):
                self.combox_port.addItem(i.name)

    def com_conn(self):
        if self.button_conn.isChecked():
            # if len(self.lineedit_password.text()) != 8:
            #     qm = QMessageBox.about(self, '提示窗口', '请输入有效密码!')
            #     self.button_conn.setChecked(False)
            # else:
            self.port = self.combox_port.currentText()
            if self.port:
                try:
                    self.ser = serial.Serial(port=self.port, baudrate=115200, bytesize=8, parity='N', stopbits=1,
                                             timeout=0.1)
                    if self.ser.isOpen():
                        self.button_state.setIcon(self.icon_green)
                        self.button_conn.setText('关闭串口')
                        self.button_reset.setEnabled(True)
                    else:
                        qm = QMessageBox.about(self, '提示窗口', '串口打开失败\n请检查后重试')
                except Exception as e:
                    print('err:', e)
                    qm = QMessageBox.about(self, '提示窗口', '串口打开失败\n请检查后重试')
            else:
                self.button_conn.setChecked(False)
                qm = QMessageBox.information(self, '提示', '选择的串口无效!\n请重新尝试!')

        else:
            if self.ser.isOpen():
                self.ser.close()
                self.button_conn.setText('打开串口')
                self.button_reset.setEnabled(False)
                self.button_state.setIcon(self.icon_red)

    def reset_tcp(self):
        if len(self.lineedit_password.text()) != 8:
            qm = QMessageBox.about(self, '提示窗口', '请输入8位有效密码!')
            return
        else:
            self.signal_operat.emit(5, 1, [None])
            self.send_data = bytearray.fromhex('FFFF') + bytearray.fromhex(self.lineedit_password.text()) + bytearray.fromhex('FFFF')
            if self.ser.isOpen():
                response = self.ser.write(self.send_data)
                result = self.ser.read(response)
                if result:
                    self.read_data = result.hex()
                    print(self.read_data)
                    if int(self.read_data[0:4], 16) == 65535 and int(self.read_data[4:8], 16) == 65535 and int(self.read_data[8:12], 16) == 65535 and int(self.read_data[12:16], 16) == 65535:
                        qm = QMessageBox.about(self, '提示窗口', '重置TCP成功!')
                    elif int(self.read_data[0:4], 16) == 65535 and int(self.read_data[4:8], 16) == 0 and int(self.read_data[8:12], 16) == 0 and int(self.read_data[12:16], 16) == 65535:
                        qm = QMessageBox.about(self, '提示窗口', '重置TCP失败!')
                    else:
                        qm = QMessageBox.about(self, '提示窗口', '无响应!')
                else:
                    qm = QMessageBox.about(self, '提示窗口', '无响应!')

    def check_change_password(self):
        """ 修改显示密码的响应 """
        if self.check_password.isChecked():
            self.lineedit_password.setEchoMode(QLineEdit.Normal)
        else:
            self.lineedit_password.setEchoMode(QLineEdit.Password)

    def get_config(self):
        self.config = {}
        if self.check_save.isChecked():
            self.config['pass_word'] = self.lineedit_password.text()
        else:
            self.config['pass_word'] =''
        self.config['check_echo'] = self.check_password.isChecked()
        self.config['check_save'] = self.check_save.isChecked()

    def closeEvent(self, event:PySide6.QtGui.QCloseEvent) -> None:
        """ 重写窗口的关闭事件 """
        self.get_config()
        super().closeEvent(event)
        self.signal_operat.emit(5, 0, [self.config])


if __name__ == "__main__":
    app = QApplication(sys.argv)
    myWin = Tcp_Reset_Manage()  # scaleRate)
    myWin.show()
    sys.exit(app.exec())
